//  
//  Sprawdzacz
//  
//  Author:
//       Grzegorz Żur <grzegorz.zur@gmail.com>
// 
//  Copyright (c) 2010-2011 Grzegorz Żur
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Text;
using System.Text.RegularExpressions;

namespace Sprawdzacz
{

	public class IBAN : Validator
	{

		public const string NAME = "IBAN";

		private static readonly Regex PATTERN = new Regex ("^[a-zA-Z]{2}[a-zA-Z0-9]{2,}$");

		private const int BASE = 10;

		private const int PREFIX = 4;

		private const int DIVIDER = 97;

		private const int REMINDER = 1;

		public IBAN () : base(NAME)
		{
		}

		public IBAN (string name) : base(name)
		{
		}

		public override Validation Validate (string number)
		{
			number = Normalize (number);
			if (!PATTERN.IsMatch (number))
				return new Validation (false, Name, number, null);
			
			string arranged = Arrange (number);
			string converted = Convert (arranged);
			int[] digits = Numbers (converted);
			int reminder = Modulo (digits, DIVIDER);
			if (reminder != REMINDER)
				return new Validation (false, Name, number, null);
			
			string message = string.Format ("{0} {1}", number.Substring (0, PREFIX), number.Substring (PREFIX));
			return new Validation (true, Name, number, message);
		}

		public override int Number (char c)
		{
			if (char.IsLetter (c))
				return char.ToUpper (c) - 'A' + BASE;
			else
				return base.Number (c);
		}

		private string Arrange (string number)
		{
			return number.Substring (PREFIX) + number.Substring (0, PREFIX);
		}

		private string Convert (string text)
		{
			StringBuilder builder = new StringBuilder ();
			for (int i = 0; i < text.Length; i++)
				builder.Append (Number (text[i]));
			return builder.ToString ();
		}
		
	}
	
}
